package org.tinygroup.bizframe.common;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.bizframe.common.impl.DefaultAuditLogger;
import org.tinygroup.cache.Cache;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.menuframe.config.Menu;
import org.tinygroup.menuframe.dto.MenuInfo;
import org.tinygroup.menuframe.dto.MenuNode;
import org.tinygroup.menuframe.manager.MenuTreeManager;

/**
 * 
 * @author Paul Wang
 *授权菜单拦截器,记录用户访问日志
 */
public class AuthInterceptor implements HandlerInterceptor {
    private static final String USER_AUTH_MENUS = "authMenus";
    private static final String USER_MENU_PATHS = "menuPaths";

    private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);
    
    private Cache cache;

    public Cache getCache() {
        return cache;
    }

    public void setCache(Cache cache) {
        this.cache = cache;
    }

    private static AuditLogger auditLogger;
    protected AuditLogger getAuditLogger(){
        if(auditLogger==null){
        	try{
        	    auditLogger = BeanContainerFactory.getBeanContainer(BaseController.class.getClassLoader()).getBean(AuditLogger.BEAN_NAME);
        	}catch(Exception e){
        		auditLogger=new DefaultAuditLogger();
        	}
        }
        return auditLogger;
    }
    

    /**
     * 登录控制
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        
    	String requestUrl = httpServletRequest.getRequestURI()
                .replace(httpServletRequest.getContextPath(), "");
        String userId = (String) httpServletRequest.getSession().getAttribute("userId");
        if((httpServletRequest.getHeader("X-Requested-With") != null  && "XMLHttpRequest".equals( httpServletRequest.getHeader("X-Requested-With").toString()))){
        	logger.logMessage(LogLevel.INFO, "[Ajax request] userId:{0},url:{1}",userId,requestUrl);
        	return true;
        }
        MenuService menuService=BeanContainerFactory.getBeanContainer(this.getClass().getClassLoader())
        		.getBean("menuService");
        List<Integer> userMenuIdList =null;
        
        if(menuService!=null){
        	userMenuIdList=menuService.findMenuIdsByUser(userId);
        }
        else{
        	//TODO 缓存应该在前面
        	userMenuIdList = (List<Integer>)(getCache().get("authMenus","listUserMenuId-"+userId));
        }
        
        
        MenuTreeManager menuTreeManager=BeanContainerFactory.getBeanContainer(this.getClass().getClassLoader())
        		.getBean("menuTreeManager");
        
        
        List<MenuNode> menuNodeList = menuTreeManager.getAuthMenuNodeList(userMenuIdList);
        
        //分成两步是为了方便缓存
        MenuInfo menuInfo = menuTreeManager.getAuthMenuInfo(requestUrl,menuNodeList);
        
        httpServletRequest.setAttribute(USER_MENU_PATHS,menuInfo.getMenuPaths());
        httpServletRequest.setAttribute(USER_AUTH_MENUS,menuInfo.getMenuList());
        if(menuInfo.getMenuPaths().size()>0){
        	Integer menuId= menuInfo.getMenuPaths().get(menuInfo.getMenuPaths().size()-1);
        	String menuName = null;
        	List<Menu> allMenu = menuTreeManager.getAllMenu(null);
        	for(Menu m : allMenu){
        		if(m.getId()==menuId.intValue()){
        			menuName =m.getMenuName();
        			break;
        		}
        	}
        	String[] data =new String[]{"auditType","功能访问","URL",requestUrl,"menuId",menuId+"","menuName",menuName};
        	getAuditLogger().logData(userId,data);
        	
        }
        
        return true;
    }


    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
    }

    /**
     * 异常处理
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
